#include "cmus-rg.h"

int frame;
/* max line width */
int max_l_w;
/* cmus state hash */
uint64_t previous_info_hash;
/* used to update album art */
bool file_changed;

track *cr_track;
player *cr_player;

void init_crg() {
    frame = 0;
    file_changed = false;

    /* calculate max line width */
    int w;
    if (TTF_SizeUTF8(font, "W", &w, NULL))
        fprintf(stderr, "TTF_SizeUTF8 error: %s\n", SDL_GetError());
    max_l_w = FIELD_W / w;

    set_render_changed();
    
    cr_track = create_track((uint64_t) 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, (uint64_t) 0, (uint64_t) 0);
    cr_player = create_player(NULL, NULL, (uint64_t) 0, (uint64_t) 0, (uint64_t) 0, false, false, false);
}

void cleanup_crg() {
    destroy_track(cr_track);
    destroy_player(cr_player);
}

void update_crg() {
    /* lazily render */
    if (render_changed || frame % 10 == 0) {
        /* query processing */
        /* update this even lazier, as it involves subprocess costs */
        if (frame % 60 == 0) {
            process_info();
        }
 
        draw_bg(BG);

        if (DEBUG)
            draw_frames(frame);
       
        /* draw processed info */
        draw_info();
        if (file_changed) {
            file_changed = false;
            draw_cover_art();
        }
    }

    frame++;
    if (frame >= 60)
        frame %= 60;
}

FILE* query_cmus() {
    FILE *fp = NULL;

    /* open command for reading */
    fp = popen("/bin/cmus-remote -Q 2>&1", "r");
    if (fp == NULL) {
        fprintf(stderr, "cmus-remote error: command not found or failed to run\n");
        exit(1);
    }

    return fp;
}

void process_info() {
    /* buffer */
    size_t max = 1024;
    char output[max];

    /* query data */
    FILE *fp = query_cmus();

    uint64_t info_hash = 0;
    /* read output one line at a time */
    while (fgets(output, sizeof(output) - 1, fp) != NULL) {
        info_hash += hash(output);

        // TODO: write streaming parser lol
        fill_track_or_player(cr_track, cr_player, output, max);
    }

    /* close once done! */
    pclose(fp);

    /* skip doing anything if info hasn't changed */
    if (previous_info_hash == info_hash)
        return;

    previous_info_hash = info_hash;

    if (DEBUG) {
        print_track(cr_track);
        print_player(cr_player);
    }
}